#include "Calculate.h"
#include "math.h"
#include <QVector>
#define _USE_MATH_DEFINES

//********************* 电场公式 *******************************
double inEleCalX(double dt, double V, double angle)
{
    //传的是角度，算的时候用弧度
    double Vx = V * cos(angle * (M_PI / 180));
    return Vx * dt;
}

double inEleCalY(double dt, double V, double angle, double CMR, bool isPos, double E, bool isUp)
{
    //竖直向上为基准方向
    double flag = 1.0;                        //标识加速度方向
    if((isPos ^ isUp))                        //加速度向下
    {
        flag = -1.0;
    }
    double a = CMR * E * flag;                //加速度，既有大小又有方向
    double Vy = V * sin(angle * (M_PI / 180));//竖直分速度，既有大小又有方向
    double Y = Vy *dt + (double)1/2 * a * dt *dt;
    return Y;

}

double inEleCalV(double dt, double V, double angle, double CMR, bool isPos, double E, bool isUp)
{
    //竖直向上为基准方向
    double Vx = V * cos(angle * (M_PI / 180));

    double flag = 1.0;                        //标识加速度方向
    if((isPos ^ isUp))                        //加速度向下
    {
        flag = -1.0;
    }
    double a = CMR * E * flag;                //加速度，既有大小又有方向
    double Vy = V * sin(angle * (M_PI / 180)) + a * dt;
    double VZ = sqrt(Vx * Vx + Vy *Vy);
    return VZ;
}

double inEleCalTan(double dt, double V, double angle, double CMR, bool isPos, double E, bool isUp)
{
    //竖直向上为基准方向
    double Vx = V * cos(angle * (M_PI / 180));

    double flag = 1.0;                        //标识加速度方向
    if((isPos ^ isUp))                        //加速度向下
    {
        flag = -1.0;
    }
    double a = CMR * E * flag;                //加速度，既有大小又有方向
    double Vy = V * sin(angle * (M_PI / 180)) + a * dt;

    return Vy / Vx;

}
//********************* 磁场公式 *******************************
double inMagCalX(double dt, double V, double angle, double CMR, bool isPos, double B, bool isOut)
{
    double flag = 1.0;   //标识角速度的方向
    if(isPos ^ isOut)
    {
       flag = 1.0;
    }
    else
    {
        flag = -1.0;
    }
    double w = CMR * B * flag;                //做圆周运动的角速度
    double angleToRad = angle * (M_PI / 180); //把入射角转化成弧度
    double X = 0.0;
    X = ((V * cos(angleToRad)) / w) * sin(w * dt)
            - ((V * sin(angleToRad)) / w) * (1 - cos(w * dt));

    return X;
}

double inMagCalY(double dt, double V, double angle, double CMR, bool isPos, double B, bool isOut)
{
    double flag = 1.0;   //标识角速度的方向
    if(isPos ^ isOut)
    {
       flag = 1.0;
    }
    else
    {
        flag = -1.0;
    }
    double w = CMR * B * flag;                //做圆周运动的角速度
    double angleToRad = angle * (M_PI / 180); //把入射角转化成弧度
    double Y = 0.0;
    Y = ((V * sin(angleToRad)) / w) * sin(w * dt)
            +((V * cos(angleToRad)) / w) * (1 - cos(w * dt));

    return Y;
}

double inMagCalR(double V, double CMR, double B)
{
    return (1 / CMR) * V / B;
}

double inMagCalT(double CMR, double B)
{
    return (1 / CMR) * 2 * M_PI / B;
}

//********************* 电磁场公式 *******************************
double inEleAndMagCalX(double dt, double V, double CMR, bool isPos, double E, bool isUp, double B, bool isOut)
{
    if(B == 0)
    {
        return inEleCalX(dt, V, 0);
    }
    else
    {
        double V0 = E / B;      //开始所需要的平衡初速度
        double w = CMR * B;     //做圆周运动的角速度

        QVector<bool> temp;
        temp.push_back(isUp);
        temp.push_back(isOut);
        temp.push_back(isPos);

        int sum = 0;
        for(auto item : temp)      //二进制转换成十进制
        {
            sum = sum * 2 + item;
        }

        double X = 0;
        if(sum == 5 || sum == 3 || sum == 4 || sum == 2)//枚举对应情况，写出相应的公式
        {
            X = (V + V0) * sin((w * dt)) / w - V0 * dt;
        }
        else
        {
            X = (V - V0) * sin((w * dt)) / w + V0 * dt;
        }

        return X;
    }

}

double inEleAndMagCalY(double dt, double V, double CMR, bool isPos, double E, bool isUp, double B, bool isOut)
{
    if(B == 0)
    {
        double Y = inEleCalY(dt, V, 0,  CMR, isPos, E, isUp);
        return Y;
    }
    else
    {
        double V0 = E / B;      //开始所需要的平衡初速度
        double w = CMR * B;     //做圆周运动的角速度

        QVector<bool> temp;
        temp.push_back(isUp);
        temp.push_back(isOut);
        temp.push_back(isPos);

        int sum = 0;
        for(auto item : temp)      //二进制转换成十进制
        {
            sum = sum * 2 + item;
        }

        double Y = 0;
        if(sum == 5 || sum == 2)//枚举对应情况，写出相应的公式
        {
            Y = -(V + V0) * cos((w * dt)) / w + (V + V0) / w;
        }
        else if(sum == 7 || sum == 0)
        {
            Y = (V - V0) * cos((w * dt)) / w - (V - V0) / w;
        }
        else if(sum == 1 || sum == 6)
        {
            Y = -(V - V0) * cos((w * dt)) / w + (V - V0) / w;
        }
        else
        {
            Y = (V + V0) * cos((w * dt)) / w - (V + V0) / w;
        }

        return Y;
    }

}

double inEleAndMagCalV(double dt, double V, double CMR, bool isPos, double E, bool isUp, double B, bool isOut)
{
    double V0 = E / B;      //开始所需要的平衡初速度
    double w = CMR * B;     //做圆周运动的角速度

    QVector<bool> temp;
    temp.push_back(isUp);
    temp.push_back(isOut);
    temp.push_back(isPos);

    int sum = 0;
    for(auto item : temp)      //二进制转换成十进制
    {
        sum = sum * 2 + item;
    }
    double Vx = 0;
    double Vy = 0;

    if(sum == 5 || sum == 2)//枚举对应情况，写出相应的公式
    {
        Vx = (V + V0) * cos((w * dt)) - V0;
        Vy = (V + V0) * sin((w * dt));
    }
    else if(sum == 7 || sum == 0)
    {
        Vx = (V - V0) * cos((w * dt)) + V0;
        Vy = -((V - V0) * sin((w * dt)));
    }
    else if(sum == 1 || sum == 6)
    {
        Vx = (V - V0) * cos((w * dt)) + V0;
        Vy = (V - V0) * sin((w * dt));
    }
    else
    {
        Vx = (V + V0) * cos((w * dt)) - V0;
        Vy = -((V + V0) * sin((w * dt)));
    }
    return sqrt(Vx * Vx + Vy * Vy);
}

double inEleAndMagCalA(double dt, double V, double CMR, bool isPos, double E, bool isUp, double B, bool isOut)
{
    double V0 = E / B;      //开始所需要的平衡初速度
    double w = CMR * B;     //做圆周运动的角速度

    QVector<bool> temp;
    temp.push_back(isUp);
    temp.push_back(isOut);
    temp.push_back(isPos);

    int sum = 0;
    for(auto item : temp)      //二进制转换成十进制
    {
        sum = sum * 2 + item;
    }
    double Vx = 0;
    double Vy = 0;

    if(sum == 5 || sum == 2)//枚举对应情况，写出相应的公式
    {
        Vx = (V + V0) * cos((w * dt)) - V0;
        Vy = (V + V0) * sin((w * dt));
    }
    else if(sum == 7 || sum == 0)
    {
        Vx = (V - V0) * cos((w * dt)) + V0;
        Vy = -((V - V0) * sin((w * dt)));
    }
    else if(sum == 1 || sum == 6)
    {
        Vx = (V - V0) * cos((w * dt)) + V0;
        Vy = (V - V0) * sin((w * dt));
    }
    else
    {
        Vx = (V + V0) * cos((w * dt)) - V0;
        Vy = -((V + V0) * sin((w * dt)));
    }
    double A = atan(Vy / Vx ) * 180 / M_PI;

    if((Vx < 0 && Vy < 0))
    {
        return A - 180;
    }
    else if((Vx < 0 && Vy > 0))
    {
        return A + 180;
    }
    else
    {
        return A;
    }
}


//科学计数法转换
double sciNotation(QString str)
{
    if(str.contains("x10^"))
    {
        str.replace("x10^","e");
    }
    double d = QString(str).toDouble();
    return d;
}


//将计算结果用科学计数法表示
QString sciResult(double res)
{
    QString b;
    if(qAbs(res)>100)
    {
        b = QString(QString::number(res, 'e', 3)).replace("e+","x10^");
    }
    else if(qAbs(res)<0.1)
    {
        b = QString(QString::number(res, 'e', 3)).replace("e-","x10^-");
    }
    else
    {
        b = QString::number(res, 10, 3);
    }
    return b;
}

double inEleCalA(double dt, double V, double angle, double CMR, bool isPos, double E, bool isUp)
{
    //竖直向上为基准方向
    double Vx = V * cos(angle * (M_PI / 180));

    double flag = 1.0;                        //标识加速度方向
    if((isPos ^ isUp))                        //加速度向下
    {
        flag = -1.0;
    }
    double a = CMR * E * flag;                //加速度，既有大小又有方向
    double Vy = V * sin(angle * (M_PI / 180)) + a * dt;

    return atan(Vy / Vx ) * 180 / M_PI;
}

double inMagCalA(double dt, double V, double angle, double CMR, bool isPos, double B, bool isOut)
{
    double flag = 1.0;   //标识角速度的方向
    if(isPos ^ isOut)
    {
       flag = 1.0;
    }
    else
    {
        flag = -1.0;
    }
    double w = CMR * B * flag ;                //做圆周运动的角速度
    double angleToRad = angle * (M_PI / 180); //把入射角转化成弧度
    double Vx = 0.0;
    Vx = ((V * cos(angleToRad)) ) * cos(w * dt)
            -((V * sin(angleToRad)) ) * ( sin(w * dt));

    //    Y = ((V * sin(angleToRad)) / w) * sin(w * dt)
    //        +((V * cos(angleToRad)) / w) * (1 - cos(w * dt));
    double Vy = 0.0;
    Vy = ((V * sin(angleToRad)) ) * cos(w * dt)
            +((V * cos(angleToRad)) ) * (sin(w * dt));
    double A = 0.0;
    A = atan(Vy / Vx ) * 180 / M_PI;

    if((Vx < 0 && Vy < 0))
    {
        return A - 180;
    }
    else if((Vx < 0 && Vy > 0))
    {
        return A + 180;
    }
    else
    {
        return A;
    }
}

double inEleAndMagCalVx(double dt, double V, double CMR, bool isPos, double E, bool isUp, double B, bool isOut)
{
    double V0 = E / B;      //开始所需要的平衡初速度
    double w = CMR * B;     //做圆周运动的角速度

    QVector<bool> temp;
    temp.push_back(isUp);
    temp.push_back(isOut);
    temp.push_back(isPos);

    int sum = 0;
    for(auto item : temp)      //二进制转换成十进制
    {
        sum = sum * 2 + item;
    }
    double Vx = 0;

    if(sum == 5 || sum == 2)//枚举对应情况，写出相应的公式
    {
        Vx = (V + V0) * cos((w * dt)) - V0;
    }
    else if(sum == 7 || sum == 0)
    {
        Vx = (V - V0) * cos((w * dt)) + V0;
    }
    else if(sum == 1 || sum == 6)
    {
        Vx = (V - V0) * cos((w * dt)) + V0;
    }
    else
    {
        Vx = (V + V0) * cos((w * dt)) - V0;
    }
    //qDebug()<<"Vx="<<Vx;
    return Vx;
}

double inEleAndMagCalVy(double dt, double V, double CMR, bool isPos, double E, bool isUp, double B, bool isOut)
{
    double V0 = E / B;      //开始所需要的平衡初速度
    double w = CMR * B;     //做圆周运动的角速度

    QVector<bool> temp;
    temp.push_back(isUp);
    temp.push_back(isOut);
    temp.push_back(isPos);

    int sum = 0;
    for(auto item : temp)      //二进制转换成十进制
    {
        sum = sum * 2 + item;
    }
    double Vy = 0;

    if(sum == 5 || sum == 2)//枚举对应情况，写出相应的公式
    {
        Vy = (V + V0) * sin((w * dt));
    }
    else if(sum == 7 || sum == 0)
    {
        Vy = -((V - V0) * sin((w * dt)));
    }
    else if(sum == 1 || sum == 6)
    {
        Vy = (V - V0) * sin((w * dt));
    }
    else
    {
        Vy = -((V + V0) * sin((w * dt)));
    }
    //qDebug()<<"Vy="<<Vy;
    return Vy;
}

double getNumLayer(QString str)
{
    double num = sciNotation(str);

    QString temp = QString::number(num, 'e', 2);

    int pos = temp.indexOf("e") + 1;

    temp = temp.mid(pos);

    return temp.toDouble();
}
